﻿using System;

namespace Grinder.Exif
{

    #region Rational Class
    internal sealed class Rational
    {
        private readonly Int32 _num;
        private readonly Int32 _denom;

        public Rational(byte[] bytes)
        {
            var n = new byte[4];
            var d = new byte[4];
            Array.Copy(bytes, 0, n, 0, 4);
            Array.Copy(bytes, 4, d, 0, 4);
            _num = BitConverter.ToInt32(n, 0);
            _denom = BitConverter.ToInt32(d, 0);
        }

        public double ToDouble()
        {
            return Math.Round(Convert.ToDouble(_num) / Convert.ToDouble(_denom), 2);
        }

        public string ToString(string separator)
        {
            return _num + separator + _denom;
        }

        public override string ToString()
        {
            return ToString("/");
        }
    }
    #endregion

    #region Rational Class
    internal sealed class URational
    {
        private readonly UInt32 _num;
        private readonly UInt32 _denom;

        public URational(byte[] bytes)
        {
            var n = new byte[4];
            var d = new byte[4];
            Array.Copy(bytes, 0, n, 0, 4);
            Array.Copy(bytes, 4, d, 0, 4);
            _num = BitConverter.ToUInt32(n, 0);
            _denom = BitConverter.ToUInt32(d, 0);
        }

        public double ToDouble()
        {
            return Math.Round(Convert.ToDouble(_num) / Convert.ToDouble(_denom), 2);
        }

        public override string ToString()
        {
            return ToString("/");
        }

        public string ToString(string separator)
        {
            return _num + separator + _denom;
        }
    }
    #endregion

    #region Rational Class
    internal sealed class GPSCoordinate
    {
        private readonly Rational _hours;
        private readonly Rational _minutes;
        private readonly Rational _seconds;

        public double Hours
        {
            get
            {
                return _hours.ToDouble();
            }            
        }
        public double Minutes
        {
            get
            {
                return _minutes.ToDouble();
            }            
        }
        public double Seconds
        {
            get
            {
                return _seconds.ToDouble();
            }            
        }

        public GPSCoordinate(byte[] bytes)
        {
            var h = new byte[8];
            var m = new byte[8];
            var s = new byte[8];

            Array.Copy(bytes, 0, h, 0, 8); Array.Copy(bytes, 8, m, 0, 8); Array.Copy(bytes, 16, s, 0, 8);

            _hours = new Rational(h);
            _minutes = new Rational(m);
            _seconds = new Rational(s);
        }

        public TimeSpan ToTimeSpan()
        {
            return new TimeSpan((int)Hours, (int)Minutes, (int)Seconds);
        }

        public override string ToString()
        {
            return _hours.ToDouble() + "° "
                + _minutes.ToDouble() + "\' "
                + _seconds.ToDouble() + "\"";
        }

        public string ToString(string separator)
        {
            return _hours.ToDouble() + separator
                + _minutes.ToDouble() + separator +
                _seconds.ToDouble();
        }
    }
    #endregion

}
